package com.chenjl.trace.model;

import java.util.ArrayList;
import java.util.List;

import com.chenjl.trace.enums.AnnotationEnum;
import com.chenjl.trace.generate.TraceTime;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
 * 链路追踪的单元
 * 2018-9-4 17:09:20
 * @author chenjinlong
 */
@Getter
@Setter
@ToString
public class Span {
	/**
	 * 全局唯一
	 */
	private String traceId;
	private String parentId = "#";
	
	private String id;
	/**
	 * HTTP服务接口 - servletPath
	 * Dubbo RPC - 类全限定名+方法名
	 * Hessian RPC - 类全限定名+方法名
	 * httpclient4 发起外部访问 - 对应的URL
	 * MySQL CRUD  - 对应的SQL
	 */
	private String name;
	/**
	 * 类型
	 * http_api
	 * dubbo_service
	 * hessian_service
	 * apache_httpclient4
	 * mysql_access
	 */
	private String spanType;
	/**
	 * 发生事件的时间戳
	 */
	private Long timestamp;
	/**
	 * 持续时间,使用的单位是微秒
	 */
	private Long duration;
	
	/**
	 * 当前站点的域名，由flume配置，不在trace-client中获取
	 */
	private String domainName;
	/**
	 * 当前站点的ip，由flume获取，不在trace-client中获取
	 */
	private String ip;
	
	/**
	 * 本次span单元的事件记录
	 */
	private List<Annotation> annotations = new ArrayList<Annotation>();
	/**
	 * 记录事件额外的RPC信息
	 */
	private List<BinaryAnnotation> binaryAnnotations = new ArrayList<BinaryAnnotation>();
	
	
	
	
	/**
	 * 增加事件的记录
	 * @param endpoint
	 * @param annotationTypeEnum
	 */
	public final void addAnnotation(Endpoint endpoint,AnnotationEnum annotationEnum) {
		Annotation annotation = new Annotation();
		annotation.setEndpoint(endpoint);
		annotation.setTimestamp(TraceTime.get());
		annotation.setValue(annotationEnum.getValue());
		
		annotations.add(annotation);
	}
	/**
	 * 增加事件的记录
	 * @param endpoint
	 * @param timestamp
	 * @param value
	 */
	public void addAnnotation(Endpoint endpoint,Long timestamp,String value) {
		Annotation annotation = new Annotation();
		annotation.setEndpoint(endpoint);
		annotation.setTimestamp(timestamp);
		annotation.setValue(value);
		
		annotations.add(annotation);
	}
	/**
	 * 增加PRC附属信息
	 * @param endpoint
	 * @param key
	 * @param value
	 */
	public final void addBinaryAnnotation(Endpoint endpoint,String key,String value) {
		BinaryAnnotation binaryAnnotation = new BinaryAnnotation();
		binaryAnnotation.setEndpoint(endpoint);
		binaryAnnotation.setKey(key);
		binaryAnnotation.setValue(value);
		
		binaryAnnotations.add(binaryAnnotation);
	}
}